package com.wpen.unit.service.system.impl;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.wpen.unit.cvt.system.UserCvt;
import com.wpen.unit.enums.UserStatus;
import com.wpen.unit.enums.YN;
import com.wpen.unit.exception.BizException;
import com.wpen.unit.infra.mybatis.system.po.UserPo;
import com.wpen.unit.infra.mybatis.system.po.UserPwdPo;
import com.wpen.unit.infra.repository.system.UserPwdRepository;
import com.wpen.unit.infra.repository.system.UserRepository;
import com.wpen.unit.security.MD5;
import com.wpen.unit.security.PasswordUtil;
import com.wpen.unit.service.system.UserService;
import com.wpen.unit.utils.IdUtil;
import com.wpen.unit.web.WebVariables;
import com.wpen.unit.web.dto.system.ChangePwdRequest;
import com.wpen.unit.web.dto.system.ChangePwdResponse;
import com.wpen.unit.web.dto.system.LoginResponse;
import com.wpen.unit.web.dto.system.SysUserAddRequest;
import com.wpen.unit.web.dto.system.SysUserAddResponse;
import com.wpen.unit.web.dto.system.SysUserEnabledRequest;
import com.wpen.unit.web.dto.system.SysUserEnabledResponse;
import com.wpen.unit.web.dto.system.SysUserListRequest;
import com.wpen.unit.web.dto.system.SysUserListResponse;
import com.wpen.unit.web.dto.system.SysUserListRowsResponse;
import com.wpen.unit.web.dto.system.SysUserModRequest;
import com.wpen.unit.web.dto.system.SysUserModResponse;
import com.wpen.unit.web.dto.system.UserInfoRequest;
import com.wpen.unit.web.dto.system.UserInfoResponse;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class UserServiceImpl implements UserService {
    @Autowired
    private UserPwdRepository userPwdRepository;
    @Autowired
    private UserRepository userRepository;

    @Override
    public LoginResponse userLogin(HttpServletRequest request, String userName, String passwd) {
        // 上送数据验证
        try {
            UserPwdPo userPwdPo = userPwdRepository.queryByLoginName(userName);
            if (userPwdPo == null) {
                throw new BizException("E01006");
            }
            String userId = userPwdPo.getUserId();
            String pwd = PasswordUtil.getInstance().encodePwd(userId, passwd);
            if (userPwdPo == null || !pwd.equals(userPwdPo.getLoginPwd())) {
                throw new BizException("E01006");
            }
            // 创建个token
            String clienthost = request.getRemoteAddr();
            String token = MD5.ecode(userId + clienthost);
            UserPo sysUser = userRepository.queryByUserId(userId);
            // 保存到session或外部redis
            // 也可以绑了客户端，做单机登录
            request.getSession().setAttribute(token, sysUser);

            LoginResponse loginResponse = new LoginResponse();
            loginResponse.setToken(token);
            loginResponse.setResetPwd(YN.No.value());
            return loginResponse;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public ChangePwdResponse changePwd(HttpServletRequest request, ChangePwdRequest changePwdParam) {
        // 从登录的session中获取当前用户
        String token = request.getHeader(WebVariables.REQUEST_HEAD_AUTH);
        UserPo userSession = (UserPo) request.getSession().getAttribute(token);
        if (userSession == null) {
            throw new BizException("E99999");
        }
        String userId = userSession.getUserId();

        ChangePwdResponse changePwd_S = new ChangePwdResponse();
        try {
            String pwd = PasswordUtil.getInstance().encodePwd(userId, changePwdParam.getLoginPwd());
            // 数据库查询
            UserPwdPo userPwdPo = userPwdRepository.queryByUserId(userId);
            if (!pwd.equals(userPwdPo.getLoginPwd())) {
                throw new BizException("E01006");
            }
            String newpwd = PasswordUtil.getInstance().encodePwd(userId, changePwdParam.getNewpwd());
            UserPwdPo newUserPwd = new UserPwdPo();
            newUserPwd.setId(userPwdPo.getId());
            newUserPwd.setLoginPwd(newpwd);
            newUserPwd.setForceMod(YN.No.value());
            userPwdRepository.updateById(newUserPwd);

            // 返回响应信息
            if (YN.Yes.value().equals(userPwdPo.getForceMod())) {
                changePwd_S.setReLogin(YN.No.value());
            } else {
                // 退出// 踢出session中的用户
                request.getSession().removeAttribute(token);

                changePwd_S.setReLogin(YN.Yes.value());
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
        return changePwd_S;
    }

    @Override
    public UserInfoResponse queryUserInfo(HttpServletRequest request, UserInfoRequest userInfoParam) {
        // 从登录的session中获取当前用户
        String token = request.getHeader(WebVariables.REQUEST_HEAD_AUTH);
        UserPo userSession = (UserPo) request.getSession().getAttribute(token);
        if (userSession == null) {
            throw new BizException("E99999");
        }
        String userId = userSession.getUserId();

        // 数据库查询
        UserPo userPo = userRepository.queryByUserId(userId);
        if (userPo == null) {
            throw new BizException("E01005");
        }
        // 返回响应信息
        UserInfoResponse userInfoResult = UserCvt.INSTANCE.queryDto2Do(userPo);
        return userInfoResult;
    }

    @Override
    @Transactional
    public SysUserAddResponse addSysUser(SysUserAddRequest sysUserAddParam) {
        // 检查用户编号，用户登录名称是否重复
        UserPo sysUserDb = userRepository.queryByUserId(sysUserAddParam.getUserId());
        if (sysUserDb != null) {
            throw new BizException("E01002");
        }
        UserPwdPo sysUserPwdDb = userPwdRepository.queryByUserId(sysUserAddParam.getUserId());
        if (sysUserPwdDb != null) {
            throw new BizException("E01002");
        }
        // 持久化操作
        UserPo sysUser = UserCvt.INSTANCE.addUserDto2Do(sysUserAddParam);
        sysUser.setId(IdUtil.nextId());
        sysUser.setCreateTime(new Date());
        sysUser.setStatus(UserStatus.Normal.value());
        sysUser.setVersion(1);
        // 保存数据
        userRepository.insert(sysUser);
        // 创建密码123456
        // 如果采用邮件发送或短信提醒，建议8位随机。
        // 默认登录需修改
        String passwd = "123456";
        UserPwdPo sysUserPwd = new UserPwdPo();
        sysUserPwd.setId(sysUser.getId());
        sysUserPwd.setLoginName(sysUserAddParam.getLoginName());
        sysUserPwd.setUserId(sysUser.getUserId());
        sysUserPwd.setErrCount(0);
        sysUserPwd.setErrTimeLogin(0);
        sysUserPwd.setForceMod(YN.Yes.value());
        // sha1 加密
        try {
            sysUserPwd.setLoginPwd(PasswordUtil.getInstance().encodePwd(sysUser.getUserId(), passwd));
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
        userPwdRepository.insert(sysUserPwd);

        // 返回响应信息
        SysUserAddResponse sysUserAddResult = new SysUserAddResponse();
        return sysUserAddResult;
    }

    @Override
    public SysUserModResponse modSysUser(SysUserModRequest sysUserModParam) {
        UserPo sysUserDb = userRepository.queryById(sysUserModParam.getId());
        if (sysUserDb == null) {
            throw new BizException("E00001", sysUserModParam.getId());
        }
        // 持久化操作
        UserPo sysUser = UserCvt.INSTANCE.modUserDto2Do(sysUserModParam);
        sysUser.setVersion(sysUserDb.getVersion());
        // 更新数据
        userRepository.updateById(sysUser);
        // 返回响应信息
        SysUserModResponse sysUserModResult = new SysUserModResponse();
        return sysUserModResult;
    }

    @Override
    public SysUserEnabledResponse enabledSysUser(SysUserEnabledRequest sysUserEnabledParam) {
        UserPo sysUserDb = userRepository.queryById(sysUserEnabledParam.getId());
        if (sysUserDb == null) {
            throw new BizException("E00001", sysUserEnabledParam.getId());
        }

        UserPo upUser = new UserPo();
        upUser.setId(sysUserDb.getId());
        upUser.setVersion(sysUserDb.getVersion());
        if (UserStatus.Normal.value().equals(sysUserDb.getStatus())) {
            upUser.setStatus(UserStatus.Closing.value());
        } else {
            upUser.setStatus(UserStatus.Normal.value());
        }
        userRepository.updateById(upUser);

        SysUserEnabledResponse enabledResponse = new SysUserEnabledResponse();
        enabledResponse.setStatus(upUser.getStatus());
        return enabledResponse;
    }

    @Override
    public SysUserListResponse queryListSysUser(SysUserListRequest sysUserListParam) {
        // 数据库查询
        int index = sysUserListParam.getIndex();
        int size = sysUserListParam.getSize();
        // 数据库查询
        UserPo userPo = UserCvt.INSTANCE.queryListDto2Do(sysUserListParam);

        long total = userRepository.count(userPo);
        List<UserPo> sysUserLists = userRepository.queryList(index, size, userPo);

        // 返回响应信息
        SysUserListResponse sysUserListResult = new SysUserListResponse();
        sysUserListResult.setTotal(total);
        if (sysUserLists != null) {
            List<SysUserListRowsResponse> listRows = sysUserListResult.getRows();
            for (UserPo inSysUser : sysUserLists) {
                SysUserListRowsResponse row = UserCvt.INSTANCE.queryListDo2Dto(inSysUser);
                
                UserPwdPo userPwdPo = userPwdRepository.queryByUserId(inSysUser.getUserId());
                row.setLoginName(userPwdPo.getLoginName());
                
                listRows.add(row);
            }
            sysUserListResult.setRows(listRows);
        }
        return sysUserListResult;
    }

}
